home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr44 / xlib50.zip / PMIO.INC < prev    next >
Text File  |  1995-02-11  |  52KB  |  1,132 lines

  1. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. ;+                                                                             +
  3. ;+                     PMIO.INC Version 2.0 Source Code                        +
  4. ;+                                                                             +
  5. ;+              Copyright 1993-1995, by TechniLib (TM) Company                 +
  6. ;+                          All Rights Reserved                                +
  7. ;+                                                                             +
  8. ;+                  SALE OR USE OF SOFTWARE DEVELOPED WITH                     +
  9. ;+                     UNREGISTERED COPIES OF THIS CODE                        +
  10. ;+                           INFRINGES COPYRIGHT                               +
  11. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  12. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  13. ;                  Protected-Mode Input/Output Procedures.
  14. ;                               Version 2.0
  15. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  16. ;
  17. ;   All PMIO procedures assume that the code is resident in a 32-bit segment.
  18. ;Other assumptions are also made, but these may be changed with conditional
  19. ;assembly directives explained below.
  20. ;   A full explanation of each IO procedure is provided above the procedure.
  21. ;The following is a brief summary:
  22. ;
  23. ;Screen Procedures
  24. ;-----------------
  25. ;
  26. ;   The screen procedures always print at the recorded BIOS cursor position and
  27. ;update the BIOS position after printing; however, they do not adjust the video
  28. ;hardware to actually relocate the cursor on the screen.  Call UPDATECSR for
  29. ;this purpose.
  30. ;   PMIO never uses DOS.  The screen procedures avoid all calls to BIOS.
  31. ;Therefore, they should function properly within interrupt handlers.
  32. ;   The screen address is assumed to be B8000H, which will be the case for
  33. ;color monitors.  For monochrome monitors, set SCRNBASEADR below to B0000H.
  34. ;
  35. ;Procedure     Description
  36. ;PCH           Print ASCII character in AL
  37. ;CRLF          Issue carriage return and line feed
  38. ;SCRLUP        Scoll screen up
  39. ;CLS           Clear screen
  40. ;SPC           Print AL spaces
  41. ;PSTR          Print zero terminated ASCII string at DS:EBX
  42. ;PESSTR        Print zero terminated ASCII string at ES:EBX
  43. ;PCSSTR        Print zero terminated ASCII string at CS:EBX
  44. ;PHB           Print BYTE in AL as hexadecimal
  45. ;PHW           Print WORD in AX as hexadecimal
  46. ;PHD           Print DWORD in EAX as hexadecimal
  47. ;PUB           Print unsigned BYTE in AL as decimal
  48. ;PUW           Print unsigned WORD in AX as decimal
  49. ;PUD           Print unsigned DWORD in EAX as decimal
  50. ;PSB           Print signed BYTE in AL as decimal
  51. ;PSW           Print signed WORD in AX as decimal
  52. ;PSD           Print signed DWORD in EAX as decimal
  53. ;PFST          Print ST of FPU using format in AX.  AH = characters to left of
  54. ;              decimal.  AL = characters to right of decimal.
  55. ;
  56. ;Keyboard Procedures
  57. ;-------------------
  58. ;
  59. ;Procedure     Description
  60. ;GETCH         Get character from keyboard in AX.  AL = either ASCII code or
  61. ;              scan code.  If sign bit of AH is set, then scan code.  Other bits
  62. ;              in AH define the state of shift and toggle keys (see procedure
  63. ;              for detail).  Character is not echoed.
  64. ;EDITSTR       Display and edit string at DS:EBX.  Call with EAX = maximum
  65. ;              length of final string.  See procedure for details.
  66. ;SETCSRPOS     Set cursor position.  Call with (AH,AL) = (row,column).  Rows
  67. ;              range from zero (top) to 24 (bottom).  Columns range from zero
  68. ;              (left) to 79 (right).
  69. ;GETCSRPOS     Get cursor position in AX.  (AH,AL) = (row,column).
  70. ;UPDATECSR     Physically relocate cursor on screen to current BIOS coordinates.
  71. ;SETCSRTYPE    Set cursor type.  Call with AL = 0 for underline, or 1 for block.
  72. ;              Call with sign bit of AL set to disable the cursor.
  73. ;SETCSR        Set cursor position and type.  Call with position in DX and type
  74. ;              in CX.  CH = start scan line, and CL = end scan line.  Scan lines
  75. ;              range from 0 (top) to 7 (bottom).
  76. ;GETCSR        Get cursor position/type in DX/CX (CH/CL = start/end scan line).
  77. ;
  78. ;Speaker Procedures
  79. ;------------------
  80. ;
  81. ;Procedure     Description
  82. ;BEEP          Produce beep through speaker.
  83. ;
  84. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  85. ;                             PMIO.INC Switches
  86. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  87. ;
  88. ;   There are two switches affecting the way PMIO.INC assembles.  Both switches
  89. ;default to FALSE.  The switches should be defined before the inclusion of
  90. ;PMIO.INC
  91. ;
  92. ;1) TASMMODE:
  93. ;
  94. ;   TASM users should set TASMMODE to TRUE.
  95. ;
  96. ;2) ASSUMEFLAT:
  97. ;
  98. ;   If it may always be assumed that DS contains a flat-model selector, then set
  99. ;ASSUMEFLAT to TRUE.  This will increase speed.
  100. ;
  101. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  102. ;               Important Changes from Earlier Version of PMIO
  103. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  104. ;
  105. ;   Many changes have been made to PMIO.INC.  Some of these may necessitate
  106. ;changes to code using earlier versions.  Important changes are:
  107. ;
  108. ;1) PSTR prints the string at DS:EBX rather than ES:EBX.  A new procedure
  109. ;   called PESSTR prints from ES:EBX.
  110. ;2) PCH, PSTR, PCSSTR, and PESSTR now translate character 13 to a carriage
  111. ;   return-linefeed combination.  13,10 is translated the same (10 is ignored).
  112. ;   Character 7 is translated to a beep at the speaker.  Earlier versions of
  113. ;   PMIO.INC did not translate control codes.
  114. ;3) The procedure PFST has been renamed to PFST.
  115. ;4) Earlier versions of PMIO.INC assumed that DS was loaded with a flat
  116. ;   selector (base = 0).   This version assumes nothing about segment
  117. ;   registers (DS is always reloaded).  This produces no incompatibility.
  118. ;   However, to emulate older versions, set ASSUMEFLAT to TRUE.
  119. ;5) The present version contains a new procedure called EDITSTR which is a
  120. ;   powerful string edit/input function.  Other new procedures have been added
  121. ;   to handle BYTE data.  These are:  PHB, PUB, and PSB.
  122. ;
  123. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  124.  
  125. TRUE           EQU            1
  126. FALSE          EQU            0
  127.  
  128.                IFDEF TASMMODE
  129. DOTASM         =              TASMMODE
  130.                ELSE
  131. DOTASM         =              FALSE
  132.                ENDIF
  133.  
  134.                IFDEF ASSUMEFLAT
  135. DOFLAT         =              ASSUMEFLAT
  136.                ELSE
  137. DOFLAT         =              FALSE
  138.                ENDIF
  139.  
  140.                IF DOTASM
  141.  
  142.                MASM51
  143.                QUIRKS
  144.                LARGESTACK
  145.  
  146. PUSHW          MACRO IMMEDIATE16:REST                       ;PUSH immediate 16-bit data
  147.                IF (@WordSize EQ 4)
  148.                DB             66H
  149.                ENDIF
  150.                DB             68H
  151.                DW             IMMEDIATE16
  152.                ENDM
  153.  
  154. PUSHD          MACRO IMMEDIATE32:REST                       ;PUSH immediate 32-bit data
  155.                IF (@WordSize EQ 2)
  156.                DB             66H
  157.                ENDIF
  158.                DB             68H
  159.                DD             IMMEDIATE32
  160.                ENDM
  161.  
  162.                ENDIF                                        ;IF DOTASM
  163.  
  164.                IF DOFLAT                                    ;DS always contains FLATDSEL
  165.  
  166. SETDS          MACRO                                        ;Does nothing
  167.                ENDM
  168.  
  169. RESETDS        MACRO                                        ;Does nothing
  170.                ENDM
  171.  
  172.                ELSE                                         ;DS must be loaded with FLATDSEL
  173.  
  174. SETDS          MACRO
  175.                PUSH           DS
  176.                MOV            DS,CS:CSDSEGSEL               ;Load DSEG selector
  177.                ASSUME         DS:DSEG
  178.                MOV            DS,FLATDSEL
  179.                ASSUME         DS:TSEG
  180.                ENDM
  181.  
  182. RESETDS        MACRO
  183.                POP            DS
  184.                ENDM
  185.  
  186.                ENDIF
  187.  
  188. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  189. ;Local Data and Constants
  190. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  191.  
  192.                ALIGN          4
  193. SCRNBASEADR    DD             000B8000H                     ;Screen address
  194. CURPOSADR      DD             00000450H                     ;BIOS address containing cursor position
  195. SCRNATR        DB             07H                           ;Attribute for CLS (white over black)
  196.  
  197. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  198. ;Screen Routines
  199. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  200.  
  201. ;Print ASCII code in AL at cursor.
  202. PCH            PROC NEAR
  203.                CMP            AL,0DH                        ;Effectively append linefeed to carriage return
  204.                JE             CRLF
  205.                CMP            AL,0AH                        ;Do nothing with linefeeds
  206.                JE             DORET
  207.                CMP            AL,7                          ;Ring bell
  208.                JE             BEEP
  209.                PUSH           EBX
  210.                PUSH           EDX
  211.                SETDS
  212.                MOV            EDX,CS:CURPOSADR              ;Cursor (row,col) in (DH,DL)
  213.                PUSH           EDX                           ;PUSH cursor address
  214.                MOV            EDX,[EDX]
  215.                PUSH           EDX                           ;PUSH cursor position
  216.                XOR            EBX,EBX
  217.                MOV            BL,DH
  218.                SHL            EBX,5                         ;Multiply row by 160
  219.                LEA            EBX,[EBX+4*EBX]               ;160 = 32 + 4 * 32
  220.                AND            EDX,0FFH                      ;Clear all but column
  221.                LEA            EBX,[EBX+2*EDX]
  222.                ADD            EBX,CS:SCRNBASEADR
  223.                POP            EDX                           ;POP cursor position
  224.                MOV            [EBX],AL
  225.                INC            DL                            ;Increment column
  226.                CMP            DL,79
  227.                JBE            RCDCURSOR
  228.                XOR            DL,DL                         ;Move to zero column of next row
  229.                INC            DH                            ;Move to next row
  230. RCDCURSOR:     POP            EBX                           ;POP cursor address
  231.                MOV            [EBX],DX                      ;Assume row is valid
  232.                CMP            DH,24
  233.                JA             DOSCROLL
  234. EXIT:
  235.                RESETDS
  236.                POP            EDX
  237.                POP            EBX
  238. DORET:         RET
  239. DOSCROLL:      PUSHD          OFFSET EXIT
  240.                JMP            SCRLUP
  241. PCH            ENDP
  242.  
  243. ;Clear from cursor to end of line and issue CRLF.  Scroll up if necessary.
  244. CRLF           PROC NEAR
  245.                PUSH           EAX
  246.                PUSH           EBX
  247.                PUSH           ECX
  248.                SETDS
  249.                MOV            EAX,CS:CURPOSADR
  250.                PUSH           EAX                           ;PUSH cursor address
  251.                MOV            EAX,[EAX]                     ;Get cursor position
  252.                PUSH           EAX                           ;PUSH cursor position
  253.                XOR            EBX,EBX
  254.                MOV            BL,AH
  255.                SHL            EBX,5                         ;Multiply row by 160
  256.                LEA            EBX,[EBX+4*EBX]               ;160 = 32 + 4 * 32
  257.                AND            EAX,0FFH                      ;Clear all but column
  258.                MOV            CL,80
  259.                SUB            CL,AL                         ;Get number of bytes to clear in CL
  260.                LEA            EBX,[EBX+2*EAX]
  261.                ADD            EBX,CS:SCRNBASEADR
  262.                MOV            AL,32
  263. CLREOL:        MOV            [EBX],AL                      ;Clear to end of line
  264.                ADD            EBX,2
  265.                DEC            CL
  266.                JNZ            CLREOL
  267.                POP            EAX                           ;POP cursor position
  268.                POP            EBX                           ;POP cursor address
  269.                INC            AH                            ;Increment row
  270.                CMP            AH,24
  271.                JA             DOSCROLL
  272.                XOR            AL,AL                         ;Set column to zero
  273.                MOV            [EBX],AX
  274. EXIT:
  275.                RESETDS
  276.                POP            ECX
  277.                POP            EBX
  278.                POP            EAX
  279.                RET
  280. DOSCROLL:      PUSHD          OFFSET EXIT
  281.                JMP            SCRLUP
  282. CRLF           ENDP
  283.  
  284. ;Scroll entire screen up one line and leave cursor at start of line 24.
  285. SCRLUP         PROC NEAR
  286.                PUSH           EAX
  287.                PUSH           EBX
  288.                PUSH           ECX
  289.                SETDS
  290.                MOV            EBX,CS:SCRNBASEADR
  291.                MOV            ECX,960                       ;960 = (80*24*2)/4 (DWORDS to scroll)
  292. SCROLLLOOP:    MOV            EAX,[EBX+160]
  293.                MOV            [EBX],EAX
  294.                ADD            EBX,4
  295.                DEC            ECX
  296.                JNZ            SCROLLLOOP
  297.                MOV            CL,80
  298.                MOV            AL,32
  299. CLR24:         MOV            [EBX],AL                      ;Clear line 24
  300.                ADD            EBX,2
  301.                DEC            CL
  302.                JNZ            CLR24
  303. EXIT:          MOV            EAX,CS:CURPOSADR
  304.                MOV            WORD PTR [EAX],1800H          ;Set cursor to bottom line in zero column
  305.                RESETDS
  306.                POP            ECX
  307.                POP            EBX
  308.                POP            EAX
  309.                RET
  310. SCRLUP         ENDP
  311.  
  312. ;Clear screen and leave cursor at (0,0) position.
  313. CLS            PROC NEAR
  314.                PUSH           EAX
  315.                PUSH           EBX
  316.                PUSH           ESI
  317.                SETDS
  318.                MOV            EBX,CS:SCRNBASEADR
  319.                MOV            ESI,999
  320.                MOV            AL,20H
  321.                MOV            AH,CS:SCRNATR
  322.                PUSH           AX
  323.                PUSH           AX
  324.                POP            EAX
  325. DOCLS:         MOV            [EBX+4*ESI],EAX
  326.                DEC            ESI
  327.                JNS            DOCLS
  328.                MOV            EAX,CS:CURPOSADR
  329.                MOV            WORD PTR [EAX],0H
  330.                RESETDS
  331.                POP            ESI
  332.                POP            EBX
  333.                POP            EAX
  334.                RET
  335. CLS            ENDP
  336.  
  337. ;Print AL spaces at cursor.
  338. SPC            PROC NEAR
  339.                OR             AL,AL
  340.                JZ             EXIT
  341.                PUSH           EAX
  342.                MOV            AH,AL
  343.                MOV            AL,32
  344. PRINTSPC:      CALL           PCH
  345.                DEC            AH
  346.                JNZ            PRINTSPC
  347.                POP            EAX
  348. EXIT:          RET
  349. SPC            ENDP
  350.  
  351. ;Print ASCIIZ string at address in DS:EBX.
  352. PSTR           PROC NEAR
  353.                PUSH           EAX
  354.                PUSH           EBX
  355. CHARLOOP:      MOV            AL,[EBX]
  356.                OR             AL,AL                         ;See if at end of string
  357.                JZ             EXIT
  358.                CALL           PCH
  359.                INC            EBX
  360.                JMP            CHARLOOP
  361. EXIT:          POP            EBX
  362.                POP            EAX
  363.                RET
  364. PSTR           ENDP
  365.  
  366. ;Print ASCIIZ string at address ES:EBX.
  367. PESSTR         PROC NEAR
  368.                PUSH           DS
  369.                PUSH           ES
  370.                POP            DS
  371.                CALL           PSTR
  372.                POP            DS
  373.                RET
  374. PESSTR         ENDP
  375.  
  376. ;Print ASCIIZ string at address CS:EBX.
  377. PCSSTR         PROC NEAR
  378.                PUSH           EAX
  379.                PUSH           EBX
  380. CHARLOOP:      MOV            AL,CS:[EBX]                   ;See if at end of string
  381.                OR             AL,AL
  382.                JZ             EXIT
  383.                CALL           PCH
  384.                INC            EBX
  385.                JMP            CHARLOOP
  386. EXIT:          POP            EBX
  387.                POP            EAX
  388.                RET
  389. PCSSTR         ENDP
  390.  
  391. ;Print hexadecimal BYTE in AL.
  392. PHB            PROC NEAR
  393.                PUSH           EAX
  394.                MOV            AH,AL
  395.                SHR            AL,4
  396.                AND            AH,0FH
  397.                ADD            AX,3030H
  398.                CMP            AL,57
  399.                JBE            FIXAH
  400.                ADD            AL,7
  401. FIXAH:         CMP            AH,57
  402.                JBE            PRINTCHARS
  403.                ADD            AH,7
  404. PRINTCHARS:    CALL           PCH
  405.                MOV            AL,AH
  406.                CALL           PCH
  407.                POP            EAX
  408.                RET
  409. PHB            ENDP
  410.  
  411. ;Print hexadecimal WORD in AX.
  412. PHW            PROC NEAR
  413.                PUSH           EAX
  414.                PUSH           ECX
  415.                PUSH           EDX
  416.                MOV            EDX,EAX
  417.                MOV            CL,4                          ;Print four nibbles
  418. CALCNIBS:      MOV            AL,DL
  419.                AND            AL,0FH
  420.                ADD            AL,48
  421.                CMP            AL,57
  422.                JBE            PUSHDIGIT
  423.                ADD            AL,7
  424. PUSHDIGIT:     PUSH           EAX
  425.                SHR            EDX,4
  426.                DEC            CL
  427.                JNZ            CALCNIBS
  428.                MOV            CL,4
  429. PRNTNIBS:      POP            EAX
  430.                CALL           PCH
  431.                DEC            CL
  432.                JNZ            PRNTNIBS
  433.                POP            EDX
  434.                POP            ECX
  435.                POP            EAX
  436.                RET
  437. PHW            ENDP
  438.  
  439. ;Print hexadecimal DWORD in EAX.
  440. PHD            PROC NEAR
  441.                PUSH           EAX
  442.                PUSH           ECX
  443.                PUSH           EDX
  444.                MOV            EDX,EAX
  445.                MOV            CL,8                          ;Print eight nibbles
  446. CALCNIBS:      MOV            AL,DL
  447.                AND            AL,0FH
  448.                ADD            AL,48
  449.                CMP            AL,57
  450.                JBE            PUSHDIGIT
  451.                ADD            AL,7
  452. PUSHDIGIT:     PUSH           EAX
  453.                SHR            EDX,4
  454.                DEC            CL
  455.                JNZ            CALCNIBS
  456.                MOV            CL,8
  457. PRNTNIBS:      POP            EAX
  458.                CALL           PCH
  459.                DEC            CL
  460.                JNZ            PRNTNIBS
  461.                POP            EDX
  462.                POP            ECX
  463.                POP            EAX
  464.                RET
  465. PHD            ENDP
  466.  
  467. ;Print unsigned BYTE in AL as decimal.
  468. PUB            PROC NEAR
  469.                PUSH           EAX
  470.                AND            EAX,0FFH
  471.                JMP            PUINT
  472. PUB            ENDP
  473.  
  474. ;Print unsigned WORD in AX as decimal.
  475. PUW            PROC NEAR
  476.                PUSH           EAX
  477.                AND            EAX,0FFFFH
  478.                JMP            PUINT
  479. PUW            ENDP
  480.  
  481. ;Print unsigned DWORD in EAX as decimal.
  482. PUD            PROC NEAR
  483.                PUSH           EAX
  484. PUINT          LABEL NEAR
  485.                PUSH           EBX
  486.                PUSH           ECX
  487.                PUSH           EDX
  488.                XOR            ECX,ECX
  489.                MOV            EBX,10
  490. CALCDIGS:      XOR            EDX,EDX
  491.                DIV            EBX
  492.                PUSH           EDX
  493.                INC            ECX
  494.                OR             EAX,EAX
  495.                JNZ            CALCDIGS
  496. PRNTDIGS:      POP            EAX
  497.                ADD            AL,48
  498.                CALL           PCH
  499.                DEC            ECX
  500.                JNZ            PRNTDIGS
  501.                POP            EDX
  502.                POP            ECX
  503.                POP            EBX
  504.                POP            EAX
  505.                RET
  506. PUD            ENDP
  507.  
  508. ;Print signed BYTE in AL as decimal.
  509. PSB            PROC NEAR
  510.                PUSH           EAX
  511.                MOVSX          EAX,AL
  512.                JMP            PSINT
  513. PSB            ENDP
  514.  
  515. ;Print signed WORD in AX as decimal.
  516. PSW            PROC NEAR
  517.                PUSH           EAX
  518.                MOVSX          EAX,AX
  519.                JMP            PSINT
  520. PSW            ENDP
  521.  
  522. ;Print signed DWORD in EAX as decimal.
  523. PSD            PROC NEAR
  524.                PUSH           EAX
  525. PSINT          LABEL NEAR
  526.                OR             EAX,EAX
  527.                JNS            PABS
  528.                PUSH           EAX
  529.                MOV            AL,"-"
  530.                CALL           PCH
  531.                POP            EAX
  532.                NEG            EAX                           ;Calculate absolute value
  533. PABS:          CALL           PUD                           ;Print absolute value
  534.                POP            EAX
  535.                RET
  536. PSD            ENDP
  537.  
  538. ;Print ST of FPU using format code in AX.  Call with lowest seven bits of AH =
  539. ;number of high-order digits plus the sign (if negative), and lowest five bits
  540. ;of AL = number of low-order digits.  Fractions are printed with leading zeros
  541. ;if the sign bit of AH is clear.  Will print numbers absolutely smaller than
  542. ;10 ^ 18 and will print up to 18 decimal places.  Will fill entire print field
  543. ;with "*" if high-order digit field is too small.  Will fill entire print field
  544. ;with ">" if number is absolutely greater than or equal to 10 ^ 18.  It is
  545. ;assumed that ST contains a valid number.  AL must not be greater than 18.
  546. PFST           PROC NEAR
  547.                LOCAL FLDWIDTH:DWORD                         ;The width of the print field
  548.                LOCAL NOHIDIGITS:DWORD                       ;Number of high-order digits
  549.                LOCAL NOLODIGITS:DWORD                       ;Number of low-order digits
  550.                LOCAL OLDCWORD:DWORD                         ;Old FPU control word
  551.                LOCAL NEWCWORD:DWORD                         ;Local FPU control word
  552.                LOCAL HIDIGITS[10]:BYTE                      ;Storage for high-order digit string
  553.                LOCAL LODIGITS[10]:BYTE                      ;Storage for low-order digit string
  554.                PUSH           EAX
  555.                PUSH           EBX
  556.                PUSH           ECX
  557.                PUSH           EDX
  558.                PUSH           ESI
  559.                PUSH           EDI
  560.                XOR            EBX,EBX                       ;Assume no leading zeros on fractions
  561.                XOR            ECX,ECX
  562. CHKLEADZERO:   OR             AH,AH                         ;Test assumption
  563.                JS             SETFLDSIZES                   ;Leading zeros are suppressed
  564.                INC            EBX                           ;Will print leading zeros
  565. SETFLDSIZES:   AND            AH,7FH                        ;Mask leading zero flag
  566.                MOV            CL,AH                         ;Set ECX = number of high order digits + sign
  567.                MOV            NOHIDIGITS,ECX
  568.                MOV            CL,AL                         ;Set ECX = number of decimal places
  569.                MOV            NOLODIGITS,ECX
  570.                ADD            AL,AH                         ;Compute field width in EAX
  571.                AND            EAX,0FFH
  572.                OR             ECX,ECX                       ;See if any low order digits
  573.                JZ             SETFLDWIDTH
  574.                INC            EAX                           ;Account for decimal point
  575. SETFLDWIDTH:   MOV            FLDWIDTH,EAX
  576.                FTST
  577.                XOR            ECX,ECX                       ;Set ECX to sign flag
  578.                FSTSW          AX
  579.                SAHF
  580.                JAE            SETCWORD
  581.                INC            ECX                           ;Number is negative
  582. SETCWORD:      FSTCW          WORD PTR OLDCWORD[0]          ;Save original control word
  583.                MOV            EAX,OLDCWORD
  584.                OR             AH,0FH                        ;Set PC to 64 bits and RC to truncate
  585.                MOV            NEWCWORD,EAX
  586.                FLDCW          WORD PTR NEWCWORD[0]
  587.                FLD            ST                            ;See if number of high order digits is greater than 18
  588.                FABS
  589.                FCOM           CS:FPPOWERTEN[8*18]
  590.                FSTSW          AX
  591.                SAHF
  592.                JAE            OVERFLOW
  593.                FLD            ST
  594.                FRNDINT
  595.                MOV            EAX,NEWCWORD
  596.                MOV            ESI,NOLODIGITS
  597.                AND            AH,03H                        ;Set RC for round to nearest
  598.                XOR            EDX,EDX
  599.                MOV            NEWCWORD,EAX
  600.                XOR            EDI,EDI
  601.                FLDCW          WORD PTR NEWCWORD[0]
  602.                FSUB           ST(1),ST                      ;Complete low order digits
  603.                FXCH
  604.                FMUL           CS:FPPOWERTEN[8*ESI]          ;Convert to integer
  605.                FRNDINT
  606.                FCOM           CS:FPPOWERTEN[8*ESI]          ;See if low order digits rounded to one
  607.                MOV            ESI,8
  608.                FSTSW          AX
  609.                SAHF
  610.                JB             WRITEDIGITS
  611.                FSTP           ST
  612.                FLD1
  613.                FADD
  614.                FLDZ                                         ;Set low order digits to zero
  615. WRITEDIGITS:   FBSTP          TBYTE PTR LODIGITS[0]
  616.                FBSTP          TBYTE PTR HIDIGITS[0]
  617. GETHIDIGIT:    OR             DL,HIDIGITS[ESI]              ;Find first nonzero digit
  618.                JNZ            CALCHIORDER
  619.                DEC            ESI
  620.                JNS            GETHIDIGIT
  621.                MOV            ESI,EBX                       ;No high order digits, so add leading zero if any
  622.                JMP            ADDSIGN
  623. CALCHIORDER:   MOV            EDI,ESI                       ;Save offset in EDI
  624.                INC            ESI                           ;Convert ESI to number of high order digits
  625.                ADD            ESI,ESI
  626.                TEST           DL,0F0H                       ;See if highest digit is in odd position
  627.                JNZ            ADDSIGN
  628.                DEC            ESI
  629. ADDSIGN:       ADD            ESI,ECX                       ;Account for possible "-"
  630.                MOV            EAX,NOHIDIGITS
  631.                SUB            EAX,ESI                       ;See if field for high-order digits and sign is large enough
  632.                JB             SMALLFLD
  633.                CALL           SPC                           ;Print leading spaces
  634. PRNTSIGN:      OR             ECX,ECX
  635.                JZ             PRNTHIDIGITS
  636.                MOV            AL,"-"
  637.                CALL           PCH
  638.                DEC            ESI
  639.                DEC            ECX                           ;Set ECX = 0
  640. PRNTHIDIGITS:  OR             ESI,ESI                       ;See if any high order digits are to be printed
  641.                JZ             PRNTDEC
  642.                AND            ESI,01H
  643.                JNZ            ODDHIDIGIT
  644. HIDIGITLOOP:   MOV            DL,HIDIGITS[EDI]
  645.                MOV            AL,DL
  646.                SHR            AL,4
  647.                ADD            AL,48
  648.                CALL           PCH
  649. ODDHIDIGIT:    MOV            AL,DL
  650.                AND            AL,0FH
  651.                ADD            AL,48
  652.                CALL           PCH
  653.                DEC            EDI
  654.                JNS            HIDIGITLOOP
  655. PRNTDEC:       OR             ECX,NOLODIGITS                ;See if any low order digits are to be printed
  656.                JZ             EXIT
  657.                MOV            EDI,ECX                       ;Find byte number for first digit
  658.                DEC            EDI
  659.                SHR            EDI,1
  660.                MOV            AL,"."
  661.                CALL           PCH
  662.                MOV            DL,LODIGITS[EDI]
  663.                AND            CL,01H
  664.                JNZ            ODDLODIGIT
  665. LODIGITLOOP:   MOV            DL,LODIGITS[EDI]
  666.                MOV            AL,DL
  667.                SHR            AL,4
  668.                ADD            AL,48
  669.                CALL           PCH
  670. ODDLODIGIT:    MOV            AL,DL
  671.                AND            AL,0FH
  672.                ADD            AL,48
  673.                CALL           PCH
  674.                DEC            EDI
  675.                JNS            LODIGITLOOP
  676. EXIT:          FLDCW          WORD PTR OLDCWORD[0]          ;Restore calling control word
  677.                POP            EDI
  678.                POP            ESI
  679.                POP            EDX
  680.                POP            ECX
  681.                POP            EBX
  682.                POP            EAX
  683.                RET
  684. FILLFLD:       MOV            ECX,FLDWIDTH
  685. RCDCHAR:       CALL           PCH                           ;Print one character even if field width is zero
  686.                DEC            ECX
  687.                JNZ            RCDCHAR
  688.                JMP            EXIT
  689. SMALLFLD:      MOV            AL,"*"
  690.                JMP            FILLFLD
  691. OVERFLOW:      FSTP           ST                            ;Pop absolute value of number
  692.                MOV            AL,">"
  693.                JMP            FILLFLD
  694.                ALIGN          8
  695. FPPOWERTEN     LABEL QWORD
  696.                DQ             1.0E0
  697.                DQ             1.0E1
  698.                DQ             1.0E2
  699.                DQ             1.0E3
  700.                DQ             1.0E4
  701.                DQ             1.0E5
  702.                DQ             1.0E6
  703.                DQ             1.0E7
  704.                DQ             1.0E8
  705.                DQ             1.0E9
  706.                DQ             1.0E10
  707.                DQ             1.0E11
  708.                DQ             1.0E12
  709.                DQ             1.0E13
  710.                DQ             1.0E14
  711.                DQ             1.0E15
  712.                DQ             1.0E16
  713.                DQ             1.0E17
  714.                DQ             1.0E18
  715. PFST           ENDP
  716.  
  717. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  718. ;Keyboard Routines
  719. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  720.  
  721. ;Get chracter from keyboard without echo.  Return ASCII code or scan code in AL.
  722. ;The sign bit of AH is set if a scan code.  The state of the shift keys is also
  723. ;in AH.  Bits of AH are defined: 0 = shift, 1 = ctrl, 2 = alt, 3 = scroll lock,
  724. ;4 = num lock, 5 = caps lock, 6 = insert.  The high word of EAX is cleared.
  725. ;Interrupts must be enabled.  If CTRL C is entered, then INT 23H is executed.
  726. GETCH          PROC NEAR
  727.                PUSH           EDX
  728.                MOV            AH,10H                        ;Remove key from type-ahead buffer.  Will wait if no key present
  729.                INT            16H                           ;Scan code in AH, ASCII code in AL
  730.                MOV            EDX,EAX
  731.                MOV            AH,12H                        ;Get state of flags
  732.                INT            16H
  733.                TEST           AL,01H                        ;Combine right and left shift keys
  734.                JZ             FIXFLAGS
  735.                OR             AL,02H
  736. FIXFLAGS:      SHR            AL,1
  737.                AND            EAX,07FH
  738.                MOV            AH,AL
  739.                MOV            AL,DL                         ;Put ASCII scan code in AL
  740.                CMP            AL,0E0H                       ;See if the character is for non-ASCII enhanced keyboard key
  741.                JE             DOSCAN
  742.                OR             AL,AL                         ;See if the character is for a non-ASCII key
  743.                JZ             DOSCAN
  744.                CMP            AL,03H                        ;See if character is CTRL C
  745.                JNE            EXIT
  746.                INT            23H                           ;Do CTRL C interrupt
  747. DOSCAN:        MOV            AL,DH                         ;Put scan code in AL
  748.                OR             AH,80H                        ;Set high bit to denote scan code
  749. EXIT:          POP            EDX
  750.                RET
  751. GETCH          ENDP
  752.  
  753. ;Display ASCIIZ string at DS:EBX at the cursor and then edit.  Call with
  754. ;EAX set to maximum length for final string (excluding terminating zero).
  755. ;Editor processes BACKSPACE, DELETE, LEFT and RIGHT ARROW, INSERT, HOME, END,
  756. ;ENTER, and all noncontrol ASCII codes.  All other keys will cause editor to
  757. ;exit with no modification to the string.  ENTER causes editor to exit with
  758. ;modifications being returned.  Leading and trailing spaces are stripped from
  759. ;the returned string.  The last typed character is returned in AX.  See GETCH
  760. ;for format of AX.
  761. EDITSTR        PROC NEAR
  762.                LOCAL STARTADR:DWORD                         ;Screen address of first character in edit field
  763.                LOCAL ENDADR:DWORD                           ;Screen address of last character in edit field
  764.                PUSH           ECX
  765.                PUSH           EDX
  766.                PUSH           ESI
  767.                IFE DOFLAT
  768.                PUSH           ES
  769.                PUSH           DS
  770.                ENDIF
  771.                PUSH           EBX
  772.                PUSH           EAX                           ;Save maximum width of string
  773.                CALL           GETCSRADR                     ;Compute starting screen address for string
  774.                MOV            STARTADR,EDX
  775.                XCHG           [ESP],EAX                     ;Put starting cursor coordinates on stack and get field width in EAX
  776.                CALL           SPC                           ;Clear display field
  777.                CALL           GETCSRADR                     ;Compute ending screen address
  778.                SUB            EDX,2
  779.                MOV            ENDADR,EDX
  780.                POP            EDX                           ;Pop original cursor coordinates
  781.                MOV            CX,0607H                      ;Specify underline cursor
  782.                CALL           SETCSR                        ;Reset cursor to beginning of field
  783.                CALL           PSTR                          ;Display string
  784.                CALL           UPDATECSR
  785.                CALL           GETCSRADR                     ;Get current cursor screen address
  786.                IFE DOFLAT                                   ;Set DS:EBX to address of string on screen
  787.                MOV            DS,CS:CSDSEGSEL
  788.                ASSUME         DS:DSEG
  789.                MOV            DS,FLATDSEL
  790.                ASSUME         DS:TSEG
  791.                ENDIF
  792.                MOV            EBX,EDX
  793.                XOR            ESI,ESI                       ;ESI = cursor mode flag (0 = insert, 1 = overtype)
  794.                JMP            GETKEY
  795. FIXCURSOR:     MOV            EAX,EBX                       ;Compute cursor coordinates from screen address in EBX
  796.                SUB            EAX,CS:SCRNBASEADR
  797.                SHR            EAX,1
  798.                MOV            DL,80
  799.                DIV            DL
  800.                XCHG           AH,AL
  801.                MOV            EDX,EAX                       ;Put coordinates in DX
  802.                MOV            CX,0607H                      ;Assume underline cursor
  803.                OR             ESI,ESI                       ;Test assumption
  804.                JZ             SETCURSOR
  805.                XOR            CH,CH                         ;Specify block cursor
  806. SETCURSOR:     CALL           SETCSR                        ;Set cursor type and position
  807. GETKEY:        CALL           GETCH                         ;Get character
  808.                OR             AH,AH                         ;See if special key
  809.                JS             DOSPECIAL
  810.                CMP            AL,8                          ;See if BACKSPACE
  811.                JE             DOBS
  812.                CMP            AL,13                         ;See if ENTER
  813.                JE             STORESTR                      ;Store string and exit
  814.                CMP            AL,32                         ;See if other control key
  815.                JB             EXIT                          ;Exit without modifying string
  816.                MOV            ECX,ENDADR                    ;See if cursor beyond field
  817.                CMP            EBX,ECX
  818.                JA             DOBEEP
  819.                OR             ESI,ESI                       ;Check cursor mode
  820.                JNZ            WRITECHAR                     ;JMP if in overtype mode
  821.                CMP            BYTE PTR [ECX]," "            ;See if field is full
  822.                JE             ENTERLOOP                     ;Perform insert
  823.                JMP            DOBEEP
  824. SHIFTRIGHT:    MOV            DL,[ECX-2]                    ;Shift characters right beginning with current character
  825.                MOV            [ECX],DL
  826.                SUB            ECX,2
  827. ENTERLOOP:     CMP            ECX,EBX
  828.                JA             SHIFTRIGHT
  829. WRITECHAR:     MOV            [EBX],AL                      ;Write character
  830.                ADD            EBX,2                         ;Advance cursor
  831.                JMP            FIXCURSOR
  832. DOBS:          CMP            EBX,STARTADR                  ;See if at first character
  833.                JE             GETKEY
  834.                SUB            EBX,2
  835.                JMP            DODELETE
  836. DOSPECIAL:     TEST           AH,07H                        ;Ensure that none of SHIFT, CTRL, or ALT were pressed
  837.                JNZ            EXIT                          ;Exit without modifying string
  838.                CMP            AL,4BH                        ;See if LEFT ARROW
  839.                JNE            CHKRIGHT
  840.                CMP            EBX,STARTADR                  ;See if already at left of field
  841.                JE             GETKEY
  842.                SUB            EBX,2                         ;Decrement cursor
  843.                JMP            FIXCURSOR
  844. CHKRIGHT:      CMP            AL,4DH                        ;See if RIGHT ARROW
  845.                JNE            CHKDEL
  846.                CMP            EBX,ENDADR                    ;See if cursor already past right of field
  847.                JA             GETKEY
  848.                ADD            EBX,2
  849.                JMP            FIXCURSOR
  850. CHKDEL:        CMP            AL,53H                        ;See if DELETE
  851.                JNE            CHKINS
  852. DODELETE:      MOV            ECX,EBX
  853.                CMP            EBX,ENDADR                    ;See if cursor beyond print field
  854.                JA             GETKEY
  855.                JE             PUTSPACE                      ;Are at terminal character
  856. SHIFTLEFT:     MOV            AL,[ECX+2]                    ;Shift characters left beginning with next character
  857.                MOV            [ECX],AL
  858.                ADD            ECX,2
  859.                CMP            ECX,ENDADR
  860.                JB             SHIFTLEFT
  861. PUTSPACE:      MOV            BYTE PTR [ECX]," "
  862.                JMP            FIXCURSOR
  863. CHKINS:        CMP            AL,52H                        ;See if INSERT
  864.                JNE            CHKHOME
  865.                XOR            ESI,01H                       ;Toggle cursor mode
  866.                JMP            FIXCURSOR
  867. CHKHOME:       CMP            AL,47H                        ;See if HOME
  868.                JNE            CHKEND
  869.                MOV            EBX,STARTADR
  870.                JMP            FIXCURSOR
  871. CHKEND:        CMP            AL,4FH                        ;See if END
  872.                JNE            EXIT
  873.                MOV            EBX,ENDADR
  874. FINDENDLOOP:   CMP            BYTE PTR [EBX]," "
  875.                JNE            GOTEND
  876.                SUB            EBX,2
  877.                CMP            EBX,STARTADR
  878.                JAE            FINDENDLOOP
  879. GOTEND:        ADD            EBX,2
  880.                JMP            FIXCURSOR
  881. STORESTR:
  882.                IFE DOFLAT
  883.                PUSH           DS                            ;Set ES to flat selector
  884.                POP            ES
  885.                LDS            EBX,[ESP]                     ;Reset DS:EBX to screen address
  886.                ELSE
  887.                MOV            EBX,[ESP]
  888.                ENDIF
  889.                MOV            ECX,STARTADR                  ;ES:ECX = address of string on screen
  890.                MOV            ESI,EBX                       ;ESI will be pointer to last nonspace character in string
  891. TRIMLOOP:
  892.                IFE DOFLAT
  893.                MOV            DL,ES:[ECX]                   ;Move past leading spaces
  894.                ELSE
  895.                MOV            DL,[ECX]
  896.                ENDIF
  897.                ADD            ECX,2
  898.                CMP            DL," "
  899.                JNE            MOVCHAR
  900.                CMP            ECX,ENDADR
  901.                JBE            TRIMLOOP
  902.                JMP            PUTZERO                       ;The string is all spaces soo return null string
  903. MOVSTRLOOP:
  904.                IFE DOFLAT
  905.                MOV            DL,ES:[ECX]
  906.                ELSE
  907.                MOV            DL,[ECX]
  908.                ENDIF
  909.                ADD            ECX,2
  910.                CMP            DL," "
  911.                JE             MOVCHAR
  912.                MOV            ESI,EBX
  913. MOVCHAR:       MOV            [EBX],DL
  914.                INC            EBX
  915.                CMP            ECX,ENDADR
  916.                JBE            MOVSTRLOOP
  917.                MOV            EBX,ESI                       ;Set EBX to position after last nonspace character
  918.                INC            EBX
  919. PUTZERO:       MOV            BYTE PTR [EBX],0H
  920. EXIT:          POP            EBX
  921.                IFE DOFLAT
  922.                POP            DS
  923.                POP            ES
  924.                ENDIF
  925.                POP            ESI
  926.                POP            EDX
  927.                POP            ECX
  928.                RET
  929. DOBEEP:        PUSHD          OFFSET GETKEY
  930.                JMP            BEEP
  931. GETCSRADR:     CALL           GETCSRPOS                     ;Get cursor coordinates
  932.                PUSH           EAX                           ;Save coordinates
  933.                XOR            EDX,EDX                       ;Multiply row by 160
  934.                MOV            DL,AH
  935.                SHL            EDX,5                         ;Multiply by 32
  936.                LEA            EDX,[EDX+4*EDX]               ;Multiply by 5
  937.                AND            EAX,0FFH                      ;Mask all but column
  938.                LEA            EDX,[EDX+2*EAX]
  939.                ADD            EDX,CS:SCRNBASEADR
  940.                POP            EAX                           ;Restore coordinates
  941.                RETN
  942. EDITSTR        ENDP
  943.  
  944. ;Set cursor position at (row,col) = (AH,AL).
  945. SETCSRPOS      PROC NEAR
  946.                PUSH           EAX
  947.                PUSH           EBX
  948.                PUSH           EDX
  949.                CMP            AH,24                         ;Do not allow row greater than 24
  950.                JBE            CHKCOL
  951.                MOV            AH,24
  952. CHKCOL:        CMP            AL,79                         ;Do not allow column greater than 79
  953.                JBE            SETCURSOR
  954.                MOV            AL,79
  955. SETCURSOR:     MOV            EDX,EAX                       ;Place coordinates in DX
  956.                XOR            EBX,EBX                       ;Use screen zero
  957.                MOV            AH,02H                        ;Function to set cursor position
  958.                INT            10H
  959.                POP            EDX
  960.                POP            EBX
  961.                POP            EAX
  962.                RET
  963. SETCSRPOS      ENDP
  964.  
  965. ;Get cursor position in (AH,AL) = (row,col)
  966. GETCSRPOS      PROC NEAR
  967.                PUSH           EBX
  968.                PUSH           ECX
  969.                PUSH           EDX
  970.                MOV            AH,03H                        ;Function to get cursor position
  971.                XOR            EBX,EBX                       ;Get position for screen zero
  972.                INT            10H                           ;Cursor position returned in DX, and type returned in CX
  973.                MOV            EAX,EDX
  974.                POP            EDX
  975.                POP            ECX
  976.                POP            EBX
  977.                RET
  978. GETCSRPOS      ENDP
  979.  
  980. ;Physically relocate the cursor on the screen to the current BIOS coordinates.
  981. UPDATECSR      PROC NEAR
  982.                PUSH           EAX
  983.                CALL           GETCSRPOS
  984.                CALL           SETCSRPOS
  985.                POP            EAX
  986.                RET
  987. UPDATECSR      ENDP
  988.  
  989. ;Set cursor type.  Call with AL = 1 for block, AL = 0 for underline, and sign
  990. ;bit of AL set to disable.
  991. SETCSRTYPE     PROC NEAR
  992.                PUSH           EAX
  993.                PUSH           ECX
  994.                MOV            AH,01H
  995.                MOV            CX,0607H                      ;Assume underline cursor
  996.                OR             AL,AL
  997.                JZ             SETCURLINES
  998.                JS             DISABLECSR
  999.                XOR            CH,CH                         ;Set to block cursor
  1000.                JMP            SETCURLINES
  1001. DISABLECSR:    MOV            CH,20H                        ;Disable cursor
  1002. SETCURLINES:   INT            10H
  1003.                POP            ECX
  1004.                POP            EAX
  1005.                RET
  1006. SETCSRTYPE     ENDP
  1007.  
  1008. ;Get cursor position and type.  Position in DX and type in CX.
  1009. GETCSR         PROC NEAR
  1010.                PUSH           EAX
  1011.                PUSH           EBX
  1012.                MOV            AH,03H                        ;Function to get cursor position
  1013.                XOR            EBX,EBX                       ;BH = page
  1014.                INT            10H                           ;(start,end) scan line for cursor in (CH,CL)
  1015.                POP            EBX                           ;(row/column) for cursor in (DH,DL)
  1016.                POP            EAX
  1017.                RET
  1018. GETCSR         ENDP
  1019.  
  1020. ;Set cursor position and type.  Call with (DH,DL) = (row,col) for cursor and
  1021. ;(CH,CL) = (start,end) scan line for cursor.
  1022. SETCSR         PROC NEAR
  1023.                PUSH           EAX
  1024.                PUSH           EBX
  1025.                MOV            AH,02H                        ;Set cursor position
  1026.                XOR            EBX,EBX                       ;Use page zero
  1027.                INT            10H
  1028.                DEC            AH                            ;Set cursor type
  1029.                INT            10H
  1030.                POP            EBX
  1031.                POP            EAX
  1032.                RET
  1033. SETCSR         ENDP
  1034.  
  1035. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1036. ;Speaker Routines
  1037. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1038.  
  1039. ;Produce beep through speaker.
  1040. BEEP           PROC NEAR
  1041.                PUSH           EAX
  1042.                PUSH           ECX
  1043.                PUSH           EDX
  1044.                IN             AL,61H
  1045.                MOV            DX,6818                       ;175 cycles/second
  1046.                CALL           SOUND
  1047.                MOV            CX,3                          ;Delay for .25 seconds
  1048.                MOV            DX,0D000H
  1049.                MOV            AH,86H
  1050.                INT            15H
  1051.                OUT            61H,AL
  1052.                POP            EDX
  1053.                POP            ECX
  1054.                POP            EAX
  1055.                RET
  1056. BEEP           ENDP
  1057.  
  1058. ;Activate speaker.  Call with frequency divisor in DX.  Divisor = 1,193,180
  1059. ;divided by cycles per second.
  1060. SOUND          PROC NEAR
  1061.                PUSH           EAX
  1062.                MOV            AL,10110110B                  ;Channel 2, LSB/MSB, mode 3, binary
  1063.                OUT            43H,AL                        ;Program the timer
  1064.                MOV            EAX,EDX
  1065.                OUT            42H,AL
  1066.                MOV            AL,AH
  1067.                OUT            42H,AL
  1068.                IN             AL,61H
  1069.                OR             AL,03H                        ;Enable speaker and use channel 2 for input
  1070.                OUT            61H,AL
  1071.                POP            EAX
  1072.                RET
  1073. SOUND          ENDP
  1074.  
  1075.                IFE DOTASM
  1076.                EXTERNDEF PASCAL PCH:NEAR
  1077.                EXTERNDEF PASCAL CRLF:NEAR
  1078.                EXTERNDEF PASCAL SCRLUP:NEAR
  1079.                EXTERNDEF PASCAL CLS:NEAR
  1080.                EXTERNDEF PASCAL SPC:NEAR
  1081.                EXTERNDEF PASCAL PSTR:NEAR
  1082.                EXTERNDEF PASCAL PESSTR:NEAR
  1083.                EXTERNDEF PASCAL PCSSTR:NEAR
  1084.                EXTERNDEF PASCAL PHB:NEAR
  1085.                EXTERNDEF PASCAL PHW:NEAR
  1086.                EXTERNDEF PASCAL PHD:NEAR
  1087.                EXTERNDEF PASCAL PUB:NEAR
  1088.                EXTERNDEF PASCAL PUW:NEAR
  1089.                EXTERNDEF PASCAL PUD:NEAR
  1090.                EXTERNDEF PASCAL PSB:NEAR
  1091.                EXTERNDEF PASCAL PSW:NEAR
  1092.                EXTERNDEF PASCAL PSD:NEAR
  1093.                EXTERNDEF PASCAL PFST:NEAR
  1094.                EXTERNDEF PASCAL GETCH:NEAR
  1095.                EXTERNDEF PASCAL EDITSTR:NEAR
  1096.                EXTERNDEF PASCAL SETCSRPOS:NEAR
  1097.                EXTERNDEF PASCAL GETCSRPOS:NEAR
  1098.                EXTERNDEF PASCAL UPDATECSR:NEAR
  1099.                EXTERNDEF PASCAL SETCSRTYPE:NEAR
  1100.                EXTERNDEF PASCAL SETCSR:NEAR
  1101.                EXTERNDEF PASCAL GETCSR:NEAR
  1102.                EXTERNDEF PASCAL BEEP:NEAR
  1103.                ELSE
  1104.                GLOBAL PASCAL PCH:NEAR
  1105.                GLOBAL PASCAL CRLF:NEAR
  1106.                GLOBAL PASCAL SCRLUP:NEAR
  1107.                GLOBAL PASCAL CLS:NEAR
  1108.                GLOBAL PASCAL SPC:NEAR
  1109.                GLOBAL PASCAL PSTR:NEAR
  1110.                GLOBAL PASCAL PESSTR:NEAR
  1111.                GLOBAL PASCAL PCSSTR:NEAR
  1112.                GLOBAL PASCAL PHB:NEAR
  1113.                GLOBAL PASCAL PHW:NEAR
  1114.                GLOBAL PASCAL PHD:NEAR
  1115.                GLOBAL PASCAL PUB:NEAR
  1116.                GLOBAL PASCAL PUW:NEAR
  1117.                GLOBAL PASCAL PUD:NEAR
  1118.                GLOBAL PASCAL PSB:NEAR
  1119.                GLOBAL PASCAL PSW:NEAR
  1120.                GLOBAL PASCAL PSD:NEAR
  1121.                GLOBAL PASCAL PFST:NEAR
  1122.                GLOBAL PASCAL GETCH:NEAR
  1123.                GLOBAL PASCAL EDITSTR:NEAR
  1124.                GLOBAL PASCAL SETCSRPOS:NEAR
  1125.                GLOBAL PASCAL GETCSRPOS:NEAR
  1126.                GLOBAL PASCAL UPDATECSR:NEAR
  1127.                GLOBAL PASCAL SETCSRTYPE:NEAR
  1128.                GLOBAL PASCAL SETCSR:NEAR
  1129.                GLOBAL PASCAL GETCSR:NEAR
  1130.                GLOBAL PASCAL BEEP:NEAR
  1131.                ENDIF
  1132.